package cn.zlp.order.service.impl;

import cn.zlp.basic.service.impl.BaseServiceImpl;
import cn.zlp.basic.util.CodeGenerateUtils;
import cn.zlp.basic.util.LoginContextUtil;
import cn.zlp.basic.util.PageList;
import cn.zlp.order.domain.AdoptOrder;
import cn.zlp.order.domain.OrderAddress;
import cn.zlp.order.mapper.AdoptOrderMapper;
import cn.zlp.order.mapper.OrderAddressMapper;
import cn.zlp.order.query.AdoptOrderQuery;
import cn.zlp.order.service.IAdoptOrderService;
import cn.zlp.org.domain.Employee;
import cn.zlp.org.mapper.EmployeeMapper;
import cn.zlp.pay.constants.PayConstants;
import cn.zlp.pay.domain.PayBill;
import cn.zlp.pay.mapper.PayBillMapper;
import cn.zlp.pay.service.IPayBillService;
import cn.zlp.pet.domain.Pet;
import cn.zlp.pet.mapper.PetMapper;
import cn.zlp.quartz.constant.JobConstants;
import cn.zlp.quartz.dto.QuartzJobInfo;
import cn.zlp.quartz.service.IQuartzService;
import cn.zlp.user.domain.Logininfo;
import cn.zlp.user.domain.User;
import cn.zlp.user.domain.UserAddress;
import cn.zlp.user.mapper.UserAddressMapper;
import cn.zlp.user.mapper.UserMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service
public class AdoptOrderServiceImpl extends BaseServiceImpl<AdoptOrder> implements IAdoptOrderService {

    @Autowired(required = false)
    private PetMapper petMapper;

    @Autowired(required = false)
    private UserMapper userMapper;

    @Autowired(required = false)
    private EmployeeMapper employeeMapper;

    @Autowired(required = false)
    private AdoptOrderMapper adoptOrderMapper;

    @Autowired(required = false)
    private UserAddressMapper userAddressMapper;

    @Autowired(required = false)
    private OrderAddressMapper orderAddressMapper;

    @Autowired(required = false)
    private PayBillMapper payBillMapper;

    @Autowired
    private IPayBillService payBillService;

    @Autowired
    private IQuartzService quartzService;

    @Override
    public String submit(Map<String, Object> params, HttpServletRequest request) {
        // 获取宠物id
        long petId = Long.parseLong(params.get("pet_id").toString());
        // 获取送货方式
        long service_method = Long.parseLong(params.get("service_method").toString());
        // 获取订单收货地址
        long address_id = Long.parseLong(params.get("address_id").toString());
        // 获取支付方式
        Long pay_method = Long.parseLong(params.get("pay_method").toString());
        Pet pet = petMapper.loadById(petId);
        // 1.1修改状态,下架
        pet.setState(0);
        // 1.2设置下架时间
        pet.setOffsaletime(new Date());
        // 2.设置领养用户
        Logininfo logininfo = LoginContextUtil.getLogininfo(request);
        // 根据登录信息获取用户对象
        User user = userMapper.findByLogininfoId(logininfo.getId());
        pet.setUser_id(user.getId());
        pet.setUser(user);
        petMapper.update(pet);
        // 3.订单 @todo
        // 3.1获取领养订单
        AdoptOrder adoptOrder = pet2AdoptOrder(pet,user);
        // 3.2保存领养订单
        adoptOrderMapper.save(adoptOrder);
        // 3.3获取订单地址对象
        UserAddress userAddress = userAddressMapper.loadById(address_id);
        OrderAddress orderAddress = userAddress2OrderAddress(userAddress,adoptOrder);
        // 3.4保存订单地址对象
        orderAddressMapper.save(orderAddress);
        // 4.1创建支付单
        PayBill payBill = initPayBill(pay_method, user, adoptOrder);
        // 保存支付单
        payBillMapper.save(payBill);
        // 4.2调用支付单支付请求接口,这样可以解耦,以后支付单请求直接传入支付单调用接口就行了
        String payData = payBillService.payRequest(payBill);
        // 返回跳转支付页面的字符串
        return payData;
    }

    private PayBill initPayBill(Long pay_method, User user, AdoptOrder adoptOrder) {
        // 新建一个支付单对象
        PayBill payBill = new PayBill();
        // 因为虽然订单和支付单属性一样,但属性名不一样,所以只有挨个设置
        // 设置摘要
        payBill.setDigest(adoptOrder.getDigest());
        // 设置售价
        payBill.setMoney(adoptOrder.getPrice());
        // 最后支付时间
        payBill.setLastPayTime(new Date(System.currentTimeMillis() + PayConstants.ORDER_TIMEOUT));
        // 设置支付渠道
        payBill.setPayChannel(pay_method);
        // 设置支付单唯一标识
        payBill.setUnionPaySn(adoptOrder.getPaySn());
        // 设置业务类型,区分什么订单,这里直接用常量类的字段
        payBill.setBusinessType(PayConstants.BUSINESS_TYPE_ADOPT);
        // 设置业务键,我们治理设置的id,用来区分订单
        payBill.setBusinessKey(adoptOrder.getId());
        // 设置支付用户id
        payBill.setUser_id(user.getId());
        // 设置支付用户昵称
        payBill.setNickName(user.getUsername());
        // 设置收款店铺id
        payBill.setShop_id(adoptOrder.getShop_id());
        QuartzJobInfo info = new QuartzJobInfo();
        info.setType(JobConstants.OVER_TIME_NO_PAY_ADOPT);
        info.setJobName(JobConstants.OVER_TIME_NO_PAY_ADOPT + adoptOrder.getPaySn());
        info.setFireDate(adoptOrder.getLastPayTime());
        Map<String,Object> map = new HashMap<>();
        map.put("orderId",adoptOrder.getId());
        info.setParams(map);
        quartzService.add(info);
        // 返回支付单对象
        return payBill;
    }

    /**
     * 管理员订单信息
     * @param adoptOrderQuery
     * @param request
     * @return
     */
    @Override
    public PageList<AdoptOrder> adminAdoptOrder(AdoptOrderQuery adoptOrderQuery, HttpServletRequest request) {
        // 获取登录信息
        Logininfo logininfo = LoginContextUtil.getLogininfo(request);
        // 根据登录信息获取管理员对象
        Employee employee = employeeMapper.findByLogininfoId(logininfo.getId());
        // 分页参数设置店铺id,有店铺id说明为店铺管理员,没有说明为平台管理员
        adoptOrderQuery.setShopId(employee.getShop_id());
        return super.pageQuery(adoptOrderQuery);
    }

    /**
     * 用户订单信息
     * @param adoptOrderQuery
     * @param request
     * @return
     */
    @Override
    public PageList<AdoptOrder> userAdoptOrder(AdoptOrderQuery adoptOrderQuery, HttpServletRequest request) {
        // 获取登录信息
        Logininfo logininfo = LoginContextUtil.getLogininfo(request);
        // 根据登录信息获取管理员对象
        User user = userMapper.findByLogininfoId(logininfo.getId());
        // 分页参数设置用户id,有用户id说明为用户,没有说明为管理员
        adoptOrderQuery.setUserId(user.getId());
        return super.pageQuery(adoptOrderQuery);
    }

    /**
     * 超时未支付取消订单
     * @param id
     */
    @Override
    public void cancelOrder(long id) {
        AdoptOrder adoptOrder = adoptOrderMapper.loadById(id);
        // 修改状态为-1,取消
        adoptOrder.setState(-1);
        adoptOrderMapper.update(adoptOrder);
        String paySn = adoptOrder.getPaySn();
        PayBill payBill = payBillMapper.loadByUnionPaySn(paySn);
        // 修改状态为-1,取消
        payBill.setState(-1);
        // 设置修改时间
        payBill.setUpdateTime(new Date());
        payBillMapper.update(payBill);
        System.out.println("取消成功!!!!");

    }

    private OrderAddress userAddress2OrderAddress(UserAddress userAddress, AdoptOrder adoptOrder) {
        // 创建订单地址对象
        OrderAddress orderAddress = new OrderAddress();
        // 直接拷贝相同属性的值
        BeanUtils.copyProperties(userAddress,orderAddress);
        // 设置订单id
        orderAddress.setOrder_id(adoptOrder.getId());
        // 设置订单单号
        orderAddress.setOrderSn(adoptOrder.getOrderSn());
        // 设置创建时间
        orderAddress.setCreateTime(new Date());
        return orderAddress;
    }

    private AdoptOrder pet2AdoptOrder(Pet pet, User user) {
        // 创建领养订单对象
        AdoptOrder order = new AdoptOrder();
        order.setDigest("[摘要]对"+pet.getName()+"领养订单！"); // 设置摘要
        order.setState(0); // 待支付
        order.setPrice(pet.getSaleprice()); // 设置销售购价
        String orderSn = CodeGenerateUtils.generateOrderSn(user.getId()); // 生成订单号
        order.setOrderSn(orderSn); // 设置订单号
        // paySn,暂时不设置,后面设置
        order.setPaySn(CodeGenerateUtils.generateUnionPaySn());
        order.setLastPayTime(new Date(System.currentTimeMillis() + PayConstants.ORDER_TIMEOUT));
        // lastConfirmTime,暂时不设置,后面设置
        order.setPet_id(pet.getId()); // 设置宠物id
        order.setUser_id(user.getId()); // 设置寻主用户id
        order.setShop_id(pet.getShop_id()); // 设置收购店铺id
        return order;
    }
}
